package com.ypy.context.beans;


import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class AbstractApplicationContext implements ApplicationContext {

	protected Map<String, Object> objectsMap = new ConcurrentHashMap<>(128);
	protected Map<Class, Object> objectsTypeMap = new ConcurrentHashMap<>(128);

	@Override
	@Nullable
	public Object getBean(String name) {
		return objectsMap.get(name);
	}

	@Override
	@Nullable
	public <T> T getBean(String name, Class<T> clazz) {
		Object obj = objectsMap.get(name);
		if (obj == null) {
			Object bean;
			if ((bean = objectsTypeMap.get(clazz)) == null) {
				for (Class<?> interfaceClazz : clazz.getInterfaces()) {
					if ((bean = objectsTypeMap.get(interfaceClazz)) != null)
						return (T) bean;
					getBean(name, interfaceClazz);
				}
				return null;
			}
			return (T) bean;
		}
		return clazz.isInstance(obj) ? clazz.cast(obj) : null;
	}

	@Override
	public boolean exists(@NonNull String name) {
		return objectsMap.get(name) == null ? false : true;
	}

	@Override
	public boolean exists(String name, Class<?> clazz) {
		if (objectsMap.get(name) == null) {
			if (objectsTypeMap.get(clazz) == null) {
				for (Class<?> interfaceClazz : clazz.getInterfaces()) {
					if (objectsTypeMap.get(interfaceClazz) != null)
						return true;
					exists(name, interfaceClazz);
				}
				return false;
			}
			return true;
		}
		return true;
	}

	/**
	 * refresh the bean factory as a template method for subClass to use.
	 */
	@Override
	public void refresh() {
		// nothing to do.

		// maybe some months latter, it will be completed to refresh the bean factory.
	}
}
